package com.algorithm.classics150.区间;

import java.util.ArrayList;

/**
 * 给你一个 无重叠的 ，按照区间起始端点排序的区间列表 intervals，其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束，并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。
 *
 * 在 intervals 中插入区间 newInterval，使得 intervals 依然按照 starti 升序排列，且区间之间不重叠（如果有必要的话，可以合并区间）。
 *
 * 返回插入之后的 intervals。
 *
 * 注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。
 *
 *
 *
 * 示例 1：
 *
 * 输入：intervals = [[1,3],[6,9]], newInterval = [2,5]
 * 输出：[[1,5],[6,9]]
 * 示例 2：
 *
 * 输入：intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
 * 输出：[[1,2],[3,10],[12,16]]
 * 解释：这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
 *
 *
 * 提示：
 *
 * 0 <= intervals.length <= 104
 * intervals[i].length == 2
 * 0 <= starti <= endi <= 105
 * intervals 根据 starti 按 升序 排列
 * newInterval.length == 2
 * 0 <= start <= end <= 105
 */
public class 插入区间_57 {

    /**
     * 主要思想就是判断新的数组和旧数组的关系，
     * 如果在旧数组左侧，直接第一个加入。（需要按序升序排序）
     * 如果在旧数组右侧，在最后加入
     * 如果有重叠，需要判断谁包含的是最大的，来合并
     */
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int left = newInterval[0];
        int right = newInterval[1];
        boolean placed = false;
        ArrayList<int[]> list = new ArrayList<>();
        for (int[] interval:intervals){
            if (interval[0] > right){
                //新数组在左边，无交集
                if (!placed){
                    list.add(new int[]{left,right});
                    placed = true;
                }
                list.add(interval);
            }else if (interval[1] < left){
                //新数组在右边，无交集
                list.add(interval);
            }else {
                //与插入区间有交集，计算它们的并集
                left = Math.min(left,interval[0]);
                right = Math.max(right,interval[1]);
            }
        }
        //最后如果没插入，需要加进去
        if (!placed){
            list.add(new int[]{left,right});
        }
        //返回二维数组
        return list.toArray(new int[list.size()][]);
    }
}
